package com.chatroomserver.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chatroomserver.constant.NotifyType;
import com.chatroomserver.dto.NotifyDto;
import com.chatroomserver.dto.UserDto;
import com.chatroomserver.entity.User;
import com.chatroomserver.exception.ChatroomException;
import com.chatroomserver.mapper.MessageMapper;
import com.chatroomserver.mapper.UserMapper;
import com.chatroomserver.service.ChatListService;
import com.chatroomserver.service.MessageService;
import com.chatroomserver.service.UserService;
import com.chatroomserver.service.WebSocketService;
import com.chatroomserver.utils.CacheUtil;
import com.chatroomserver.vo.user.RegisterVo;
import com.chatroomserver.vo.user.UpdateUserVo;
import lombok.Value;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.time.LocalDate;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Resource
    UserMapper userMapper;

    @Resource
    WebSocketService webSocketService;

    @Resource
    CacheUtil cacheUtil;

    @Resource
    ChatListService chatListService;

    @Resource
    @Lazy
    MessageService messageService;

    @Override
    public boolean isExist(String name, String email) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getName, name)
                .or().eq(User::getEmail, email);
        return count(queryWrapper) > 0;
    }

    @Override
    public User getUserByNameOrEmail(String name, String email) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getName, name)
                .or().eq(User::getEmail, email);
        return getOne(queryWrapper);
    }

    @Override
    public User getUserByName(String name) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getName, name);
        return getOne(queryWrapper);
    }

    @Override
    public User register(RegisterVo registerVo) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getName, registerVo.getName())
                .or()
                .eq(User::getEmail, registerVo.getEmail());
        User existingUser = getOne(queryWrapper);

        if (existingUser != null) {
            if (registerVo.getName().equals(existingUser.getName())) {
                throw new ChatroomException("用户名已被使用~");
            }
            if (registerVo.getEmail().equals(existingUser.getEmail())) {
                throw new ChatroomException("邮箱已被使用~");
            }
        }
        User user = new User();
        user.setId(IdUtil.simpleUUID());
        user.setName(registerVo.getName());
        user.setEmail(registerVo.getEmail());
        user.setPassword(registerVo.getPassword());
        user.setType("user");
        save(user);
        return user;
    }

    @Override
    public UserDto getUserById(String userId) {
        return userMapper.getUserById(userId);
    }

    @Override
    public List<UserDto> listUser() {
        return userMapper.listUser();
    }

    @Override
    public List<String> onlineWeb() {
        return webSocketService.getOnlineUser();
    }

    @Override
    public Map<String, UserDto> listMapUser() {
        return userMapper.listMapUser();
    }

    @Override
    public void online(String userId) {
        NotifyDto notifyDto = new NotifyDto();
        notifyDto.setTime(new Date());
        notifyDto.setType(NotifyType.Web_Online);
        notifyDto.setContent(JSONUtil.toJsonStr(getUserById(userId)));
        webSocketService.sendNotifyToGroup(notifyDto);
    }

    @Override
    public void offline(String userId) {
        NotifyDto notifyDto = new NotifyDto();
        notifyDto.setTime(new Date());
        notifyDto.setType(NotifyType.Web_Offline);
        notifyDto.setContent(JSONUtil.toJsonStr(getUserById(userId)));
        //离线更新，已读列表（防止用户直接关闭浏览器等情况）
        chatListService.read(userId, cacheUtil.getUserReadCache(userId));
        webSocketService.sendNotifyToGroup(notifyDto);
    }

    @Override
    public void deleteExpiredUsers(LocalDate expirationDate) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.lt(User::getLoginTime, expirationDate);
        if (remove(queryWrapper)) {
            log.info("---清理过期用户成功---");
        }
    }


    @Override
    public boolean updateUser(String userid, UpdateUserVo updateUserVo) {
        User user = getUserByName(updateUserVo.getName());
        if (user != null) {
            if (!user.getId().equals(userid))
                throw new ChatroomException("用户名已被使用~");
        } else {
            user = getById(userid);
        }
        user.setName(updateUserVo.getName());
        user.setAvatar(updateUserVo.getAvatar());
        user.setPassword(updateUserVo.getPassword());
        boolean result = updateById(user);
        //级联更新 chat_list 中 target_info 的 avatar 字段
        if (result && user.getAvatar() != null) {
            chatListService.updateTargetAvatar(userid, user.getAvatar());
        }

        return result;
    }

    @Override
    public boolean deleteUser(String userId) {
        // 获取用户信息用于校验
        User user = getById(userId);
        if (user == null) {
            throw new ChatroomException("用户不存在");
        }
        // 删除聊天记录
        chatListService.deleteByUserId(userId);
        // 删除消息记录
        messageService.deleteByUserId(userId);
        // 删除用户自身
        return removeById(userId);
    }


    public String uploadAvatar(MultipartFile file, String userId) {
        if (file.isEmpty()) {
            throw new ChatroomException("请选择要上传的头像");
        }
        String avatarPath = "uploads/avatars/";
        // 获取项目运行目录：System.getProperty("user.dir")
        String rootPath = System.getProperty("user.dir");
        String avatarDir = "uploads" + File.separator + "avatars";
        String fullPath = rootPath + File.separator + avatarDir + File.separator;

        // 创建目录（如果不存在）
        File dir = new File(fullPath);
        if (!dir.exists()) {
            dir.mkdirs();
        }

        // 生成唯一文件名
        String originalFilename = file.getOriginalFilename();
        String ext = "";
        if (originalFilename != null && originalFilename.contains(".")) {
            ext = originalFilename.substring(originalFilename.lastIndexOf("."));
        }
        String newFileName = "avatar_" + userId + "_" + System.currentTimeMillis() + ext;

        // 保存文件
        try {
            file.transferTo(new File(fullPath + newFileName));
        } catch (IOException e) {
            throw new ChatroomException("头像上传失败");
        }

        // 更新用户头像字段
        User user = getById(userId);
        if (user == null) {
            throw new ChatroomException("用户不存在");
        }
        String avatarUrl = "http://localhost:9200/uploads/avatars/" + newFileName;
        user.setAvatar(avatarUrl);
//        updateById(user);

        return avatarUrl;
    }


}
